﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Sern.Abstracts.Tracker.DataContracts;
using Sern.Abstracts.Tracker.ServiceContracts;
using Sern.Common;

namespace Sern.ServiceImplementation.MapReduce
{
    public static class MapReduceClientTrackerProxyFactory
    {
        [Obsolete("There is an easier way, see the single argument method.")]
        public static IClient<ITracker> CreateProxy(BindingScheme bindingInfo,  string trackerUri)
        {
            var chanFactory = new ChannelFactory<ITracker>(bindingInfo.Binding, trackerUri);
            return chanFactory.CreateChannel().Wrap();
        }

        public static IClient<ITracker> CreateProxy2(BindingScheme bindingInfo, string hostName)
        {
            var chanFactory = new ChannelFactory<ITracker>(bindingInfo.Binding, bindingInfo.GetEndpointUri(hostName).AbsoluteUri);
            return chanFactory.CreateChannel().Wrap();
        }

        [Obsolete("Use the more generic method below.")]
        public static IClient<ITrackerTelemetryReceiver> CreateTelemetryProxy(BindingScheme bindingInfo, string trackerUri)
        {
            var chanFactory = new ChannelFactory<ITrackerTelemetryReceiver>(bindingInfo.Binding, trackerUri);
            return chanFactory.CreateChannel().Wrap();
        }

        public static IClient<T> CreateTrackerProxy<T>(this Func<IClient<ITracker>> tracker)
        {

            ClientType clientType = ComponentLocator.Unity.Resolve<IClientTypeToEnumMapper>()[typeof (T)];
            var bindingInfo = ComponentLocator.Unity.Resolve<IBindingFactory>()[
                clientType]();

            var uri = tracker()
                            .Proxy
                            .FindActiveClientInfo(
                                ComponentLocator.Unity.Resolve<Guid>("ClientJobId"),
                                clientType,
                                Guid.Empty,
                                Guid.Empty,
                                null,
                                null).Uri;

            var channelFactory = new ChannelFactory<T>(bindingInfo.Binding, uri);

            return channelFactory.CreateChannel().Wrap();
        }
    }
}
